<template>
  <div class="chat-container">
    <div class="chat-messages client-chat">
      <!-- AI欢迎消息 -->
      <div class="message" v-if="isWeclome">
        <div class="header-bubble">
          <div class="bubble-container">
            <div class="gif-container">
              <img src="@/assets/img/logo.png" alt="AI助手">
            </div>

            <div class="welcome-content">
              <div class="welcome-title">Hi！我是AI助手，很高兴为您服务~</div>
              <div class="welcome-txt">
                我专注于提供专业咨询服务，请问您需要了解哪方面的问题，我将为您提供相关解答以供参考。
              </div>
              <!--
              <div class="suggestions-title">您可以这样问一问~</div>
              
              <div class="suggestions">
                <div class="suggestion" v-for="item in suggestionList" :key="item.id" @click="askByReference(item.value)">
                  <i :class="item.icon"></i>
                  <div>{{ item.name }}</div>
                </div>
            
              </div>
              -->
            </div>
          </div>
        </div>
      </div>

      <div v-for="(item, index) in msgList" :key="index">
        <!-- 时间戳 -->
        <div class="timestamp"
          v-if="index === 0 || (index !== 0 && item.timestamp && (Number(item.timestamp) - Number(msgList[index - 1].timestamp)) > timestampGap)">
          {{ formatTime(item.timestamp) }}
        </div>

        <!-- 用户消息 -->
        <div class="message user-message" v-if="item.is_from_self">
          <div class="q-loading" v-if="item.is_loading">
            <i class="el-icon-loading"></i>
          </div>
          <div class="message-bubble user-bubble">
            <div class="message-content">
              <!-- 文件显示 -->
              <div class="message-files" v-if="item.files && item.files.length > 0">
                <div class="file-attachment" v-for="file in item.files" :key="file.id">
                  <i class="el-icon-document"></i>
                  <span class="file-name">{{ file.fileName }}</span>
                  <span class="file-size">({{ formatFileSize(file.fileSize) }})</span>
                </div>
              </div>
              <!-- 文本内容 -->
              <div class="question-text" style="max-width: 352px; margin-right: 8px;" v-html="formatMessage(item.content)">
              </div>
            </div>
          </div>
          <div class="message-avatar user-avatar-small">
            <i class="fas fa-user"></i>
          </div>
        </div>

        <!-- AI回复消息 -->
        <div class="message" v-if="!item.is_from_self">
          <div class="ai-avatar-small">
            <img src="@/assets/img/logo.png" alt="logo">
          </div>
          <div class="message-bubble ai-bubble">
            <div class="message-content">
              <!-- 回复主体 -->
              <div class="answer-text" v-html="formatMessage(item.content)"></div>
              
              <!-- 加载状态提示 -->
              <div class="loading" v-if="item.loading_message && !item.content">正在思考中...</div>
              <div class="loading" v-if="item.loading_message && item.content">正在生成中...</div>

              <!-- 答案的底部操作栏 -->
              <div v-show="item.is_final">
                <div class="answer-option" v-show="item.showOption">
                  <div class="answer-btn" @click="handlePlayAudio(item)">
                    <el-tooltip width="50" :content="(item.isPlaying && item.record_id == record_id ) ? '停止播报' : '开始播报'" trigger="hover"
                      :visible-arrow="true" popper-class="answer-popover">
                      <i class="el-icon-headset" v-if="!(item.isPlaying && item.record_id == record_id )"></i>
                      <i class="el-icon-video-pause" v-else></i>
                    </el-tooltip>
                  </div>
                  <div class="answer-btn" @click="copyContent(item)">
                    <el-tooltip content="复制" trigger="hover">
                      <i class="el-icon-copy-document"></i>
                    </el-tooltip>
                  </div>
                  <div class="answer-btn">
                    <el-tooltip content="该答案由AI助手生成，请谨慎甄别" trigger="hover">
                      <i class="el-icon-warning-outline"></i>
                    </el-tooltip>
                  </div>
                  <div class="answer-btn">
                    <el-tooltip content="点赞（暂未实现）" width="50" trigger="hover">
                      <i class="el-icon-thumb"></i>
                    </el-tooltip>
                  </div>
                  <div class="answer-btn">
                    <el-tooltip content="点踩（暂未实现）" trigger="hover">
                      <i class="el-icon-thumb"></i>
                    </el-tooltip>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <!-- 分割线 -->
        <el-divider v-if="item.start_new_conversation"
          :style="{ color: '#ccc', borderColor: '#ccc', padding: '0 16px' }">
          以下是新对话
        </el-divider>
      </div>

    </div>

    <div class="input-area">
      <!-- 按钮组容器 -->
      <div class="btn-group">
        <div class="btn-group-left">
            <!--
          <button class="action-btn" @click="bullhornPlayHandler">
            <i class="el-icon-volume2" v-show="bullhornOpen"></i>
            <i class="el-icon-video-pause" v-show="!bullhornOpen"></i>
            语音播报
          </button>
          
          <button class="action-btn" @click="phoneCallHandler">
            <i class="el-icon-phone"></i> AI语音通话
          </button>
          -->
          <button class="action-btn" @click="onStopStream" v-show="answering">
            <i class="el-icon-video-pause"></i> 停止生成
          </button>
        </div>
        
      </div>

      <div class="input-box">
        <!-- 文件上传按钮 -->
        <div class="file-upload-container">
          <input 
            type="file" 
            ref="fileInput" 
            @change="onFileSelected" 
            accept="image/*,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            style="display: none;"
          />
          <button class="file-upload-btn" @click="triggerFileUpload" :disabled="answering || isThinking">
            <i class="el-icon-paperclip"></i>
          </button>
        </div>
        
        <!-- 已选择的文件显示 -->
        <div class="selected-files" v-if="selectedFiles.length > 0">
          <div class="file-item" v-for="(file, index) in selectedFiles" :key="index">
            <i class="el-icon-document"></i>
            <span class="file-name">{{ file.name }}</span>
            <span class="file-size">({{ formatFileSize(file.size) }})</span>
            <button class="remove-file-btn" @click="removeFile(index)">
              <i class="el-icon-close"></i>
            </button>
          </div>
        </div>
        
        <!--
        <el-tooltip ref="popoverRecord" trigger="hover" width="50" :content="recordTip" placement="right">
          <button class="send-btn record-btn" v-popover:popoverRecord @click="startRadios" v-show="recordState == 0">
            <i class="el-icon-microphone"></i>
          </button>
        </el-tooltip>
        <button class="send-btn record-btn record-btn1" v-popover:popoverRecord @click="endRadios(true)"
          v-show="recordState == 1">
          <i class="el-icon-video-pause"></i>
        </button>
        <button class="send-btn record-btn" v-popover:popoverRecord v-show="recordState == 2">
          <i class="el-icon-loading"></i>
        </button>
    -->
        <textarea v-model="question" :readonly="answering || isThinking" :placeholder="questionTip"
          @keyup.enter="onSendQuestion"></textarea>
        <button class="send-btn" @click="onSendQuestion" v-show="!answering">
          <i class="el-icon-position"></i>
        </button>
        <button class="send-btn" @click="onStopStream" v-show="answering">
          <i class="el-icon-video-pause"></i>
        </button>
        <div class="btn-group-right">
          <button class="action-btn" @click="clearChatHandler">
            <i class="el-icon-delete"></i> 清除上下文
          </button>
        </div>
      </div>
      <div class="tip">内容由AI生成，仅供参考</div>
    </div>
  </div>
</template>

<script>
import { Message } from 'element-ui';
import { sendChatMessageStream } from '@/api/ai/chat';
import { formatTime, formatMessage, copyToClipboard } from '@/utils/chatUtils';
import { nativeTextToSpeech, stopAllAudio } from '@/utils/voiceUtils';
import { MESSAGE_TYPE } from '@/utils/constants';
import { getCurrentUserId } from '@/utils/userService';

export default {
  name: 'ClientChat',
  data() {
    return {
      question: '', // 客户输入的问题
      inputFocus: false,
      answering: false, // 回答中
      isThinking: false, // 是否思考中
      bullhornOpen: false, // 全局语音开关
      isCalling: false,
      selectedFiles: [], // 已选择的文件列表
      uploadingFiles: false, // 是否正在上传文件
      suggestionList: [{
        id: 1,
        icon: 'el-icon-question',
        name: '什么是人工智能？',
        value: '什么是人工智能？'
      }, {
        id: 2,
        icon: 'el-icon-edit',
        name: '如何学习编程？',
        value: '如何学习编程？'
      }, {
        id: 3,
        icon: 'el-icon-sunrise',
        name: '天气查询',
        value: '今天天气怎么样？'
      }],
      recordTip: '语音输入（转文字）',
      startY: 0,
      moveY: 0,
      timeNum: 0,
      /** 录音状态，0-未开启，1-录制中，2-发送中 */
      recordState: 0,
      isRadiosShow: false,
      reqId: '',
      antiShake: false,
      pressPlayCount: 0,
      audioUrl: [],
      currentAudio: null,
      feedbackOpen: false,
      curFeedbackItem: null,
      isFeedbackLoading: false,
      loading: false,
      historyLoading: false,
      timestampGap: 5 * 60, // 两次问题间隔大于5min，则展示时间戳（接口侧返回的时间戳是秒级）
      msgList: [], // 对话消息列表
      chatBoxHeight: document.body.clientHeight,
      jsScrolling: false,
      userScrolling: false,
      newAnswerContent: '',//最新的消息内容
      answerContent: '',//用于临时保存消息
      speed: 30, // 毫秒/字符
      chunkSize: 1,  // 每次渲染字符数
      isTyping: false,
      chatsContent: [],
      type: null,
      is_final_number: null,//答案一共几个字
      currentStream: null,
      record_id: null
    };
  },
  props: {
    isWeclome: {
      type: Boolean,
      default: true
    },
    currentConversation: {
      type: Object,
      default: null
    },
    userId: {
      type: String,
      default: ''
    }
  },
  computed: {
    questionTip() {
      let tip = this.answering ? '答案生成中...' : '请简要描述您的问题，避免出现具体事例和个人信息'
      if (this.recordState == 1) {
        tip = '语音录制中，请描述您的问题';
      } else if (this.recordState == 2) {
        tip = '正在识别语音内容...';
      }
      return tip;
    }
  },
  created() {
    // 监听用户端/管理端体验侧的ws事件
    this.listenClientAndManageEvent();
    // 监听公共的ws事件
    this.listenCommonEvent();
  },
  mounted() {
    document.addEventListener('click', this.handleOutsideClick);

    const sDom = document.querySelector('.chat-messages');
    if (sDom) {
      sDom.addEventListener('scroll', () => {
        if (this.msgList.length > 0 && this.msgList[this.msgList.length - 1].is_final === false && !this.jsScrolling) {
          this.userScrolling = true;
        } else {
          this.jsScrolling = false;
        }
      });
    }
  },
  beforeDestroy() {
    // 移除全局事件监听器
    document.removeEventListener('click', this.handleOutsideClick);
    if (this.currentStream) {
      this.currentStream.abort();
    }
  },
  methods: {
    // 由父级或外部触发的统一入口，避免父子重复发送
    beginQuestion(q) {
      if (typeof q === 'string') {
        this.question = q
      }
      this.onSendQuestion()
    },
    // 工具函数
    formatTime,
    formatMessage,
    
    /**
     * 文件上传相关方法
     */
    triggerFileUpload() {
      console.log('📎 触发文件上传按钮点击');
      console.log('当前状态 - answering:', this.answering, 'isThinking:', this.isThinking);
      console.log('fileInput ref:', this.$refs.fileInput);
      
      if (this.$refs.fileInput) {
        this.$refs.fileInput.click();
        console.log('✅ 已触发文件选择器');
      } else {
        console.error('❌ fileInput ref 未找到');
      }
    },
    
    onFileSelected(event) {
      console.log('📁 文件选择事件触发');
      console.log('选择的文件:', event.target.files);
      
      const files = Array.from(event.target.files);
      console.log('文件数组:', files);
      
      if (files.length > 0) {
        console.log('开始验证文件:', files.map(f => ({ name: f.name, size: f.size, type: f.type })));
        this.validateAndAddFiles(files);
      } else {
        console.log('没有选择文件');
      }
      
      // 清空input的值，允许重复选择同一文件
      event.target.value = '';
    },
    
    validateAndAddFiles(files) {
      console.log('🔍 开始验证文件:', files.length, '个文件');
      
      const maxSize = 10 * 1024 * 1024; // 10MB
      const allowedTypes = [
        'image/png',
        'image/jpeg', 
        'image/jpg',
        'image/webp',
        'image/gif',
        'application/pdf',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      ];
      
      files.forEach((file, index) => {
        console.log(`📄 验证文件 ${index + 1}:`, {
          name: file.name,
          size: file.size,
          type: file.type
        });
        // 检查文件类型
        if (!allowedTypes.includes(file.type)) {
          console.log(`❌ 文件类型不支持: ${file.name} (${file.type})`);
          Message.error(`不支持的文件类型: ${file.name} (${file.type})`);
          return;
        }
        console.log(`✅ 文件类型验证通过: ${file.type}`);
        
        // 检查文件大小
        if (file.size > maxSize) {
          console.log(`❌ 文件大小超限: ${file.name} (${this.formatFileSize(file.size)})`);
          Message.error(`文件大小超过限制: ${file.name} (${this.formatFileSize(file.size)})`);
          return;
        }
        console.log(`✅ 文件大小验证通过: ${this.formatFileSize(file.size)}`);
        
        // 检查是否已存在同名文件
        if (this.selectedFiles.some(f => f.name === file.name && f.size === file.size)) {
          console.log(`⚠️ 文件已存在: ${file.name}`);
          Message.warning(`文件已存在: ${file.name}`);
          return;
        }
        
        // 添加到选择列表
        this.selectedFiles.push(file);
        console.log(`✅ 文件添加成功: ${file.name}`);
      });
    },
    
    removeFile(index) {
      this.selectedFiles.splice(index, 1);
    },
    
    formatFileSize(bytes) {
      if (bytes === 0) return '0 B';
      const k = 1024;
      const sizes = ['B', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    },
    
    async uploadFiles() {
      if (this.selectedFiles.length === 0) return [];
      
      this.uploadingFiles = true;
      const uploadedFiles = [];
      
      try {
        // 获取当前用户ID（异步）
        const userId = await this.getCurrentUserId();
        for (const file of this.selectedFiles) {
          const formData = new FormData();
          formData.append('file', file);
          formData.append('userId', userId);
          
          const response = await fetch('/dev-api/api/ai/chat/upload', {
            method: 'POST',
            body: formData
          });
          
          const result = await response.json();
          console.log('文件上传响应:', result);
          console.log('响应格式检查:', {
            hasCode: 'code' in result,
            hasSuccess: 'success' in result,
            code: result.code,
            success: result.success,
            msg: result.msg,
            message: result.message
          });
          
          // 检查ResponseResult格式的响应 (code: 200 表示成功)
          if (result.code === 200) {
            // 从Dify响应中提取文件ID
            const difyFileInfo = this.extractDifyFileInfo(result.data);
            
            uploadedFiles.push(difyFileInfo);
            console.log('文件上传成功:', result.data);
            console.log('提取的Dify文件信息:', difyFileInfo);
          } else {
            Message.error(`文件上传失败: ${file.name} - ${result.msg || result.message}`);
          }
        }
        
        if (uploadedFiles.length > 0) {
          Message.success(`成功上传 ${uploadedFiles.length} 个文件`);
          this.selectedFiles = []; // 清空已选择的文件
        }
        
      } catch (error) {
        console.error('文件上传异常:', error);
        Message.error('文件上传失败: ' + error.message);
      } finally {
        this.uploadingFiles = false;
      }
      
      return uploadedFiles;
    },
    
    /**
     * 从Dify响应中提取文件信息
     */
    extractDifyFileInfo(fileData) {
      try {
        // 解析Dify响应
        console.log('fileData:==============================', fileData);
        let difyResponse = null;
        if (fileData.difyResponse) {
          difyResponse = typeof fileData.difyResponse === 'string' 
            ? JSON.parse(fileData.difyResponse) 
            : fileData.difyResponse;
        }
        
        console.log('解析Dify响应:', difyResponse);
        
        // 提取文件ID和类型
        const uploadFileId = difyResponse?.id || difyResponse?.file_id || difyResponse?.upload_file_id;
        const fileType = this.getFileTypeFromMimeType(fileData.fileType);
        
        if (!uploadFileId) {
          console.warn('未找到Dify文件ID:', difyResponse);
          return {
            type: fileType,
            transfer_method: 'local_file',
            upload_file_id: null,
            fileName: fileData.fileName,
            fileSize: fileData.fileSize,
            originalData: fileData
          };
        }
        
        return {
          type: fileType,
          transfer_method: 'local_file',
          upload_file_id: uploadFileId,
          fileName: fileData.fileName,
          fileSize: fileData.fileSize,
          originalData: fileData
        };
        
      } catch (error) {
        console.error('解析Dify文件信息失败:', error);
        return {
          type: 'unknown',
          transfer_method: 'local_file',
          upload_file_id: null,
          fileName: fileData.fileName,
          fileSize: fileData.fileSize,
          originalData: fileData
        };
      }
    },
    
    /**
     * 根据MIME类型获取文件类型
     */
    getFileTypeFromMimeType(mimeType) {
      if (!mimeType) return 'unknown';
      
      if (mimeType.startsWith('image/')) {
        return 'image';
      } else if (mimeType === 'application/pdf') {
        return 'document';
      } else if (mimeType.includes('word') || mimeType.includes('document')) {
        return 'document';
      } else if (mimeType.includes('excel') || mimeType.includes('spreadsheet')) {
        return 'document';
      } else {
        return 'document'; // 默认为文档类型
      }
    },
    
    /**
     * 构建Dify格式的文件信息
     */
    buildDifyFiles(files) {
      if (!files || files.length === 0) {
        return [];
      }
      
      console.log('构建Dify文件信息:', files);
      
      return files.map(file => {
        // 如果文件已经有Dify格式，直接返回
        if (file.type && file.transfer_method && file.upload_file_id) {
          console.log('使用已有的Dify文件格式:', file);
          return {
            type: file.type,
            transfer_method: file.transfer_method,
            upload_file_id: file.upload_file_id
          };
        }
        
        // 否则构建新的Dify格式
        const difyFile = {
          type: file.type || 'document',
          transfer_method: 'local_file',
          upload_file_id: file.upload_file_id || file.id || null
        };
        
        console.log('构建的Dify文件格式:', difyFile);
        return difyFile;
      }).filter(file => file.upload_file_id); // 只包含有有效文件ID的文件
    },
    
    /**
     * 发送问题
     */
    async onSendQuestion() {
      if (!this.question.trim() && this.selectedFiles.length === 0) {
        Message.warning('不能发送空白消息哦')
        return;
      }

      // 检查当前会话ID是否为UUID格式
      const currentConversationId = this.currentConversation ? this.currentConversation.id : null;
      if (currentConversationId && !this.isValidUUID(currentConversationId)) {
        console.warn('⚠️ 当前会话ID不是UUID格式，无法发送消息:', currentConversationId);
        Message.error('会话ID格式不正确，无法发送消息。请重新开始对话。');
        return;
      }

      // 如果正在生成答案，则停止
      if (this.answering) {
        this.onStopStream();
      } else {
        //结束语音播报
        this.handleStopAllAudio();
        
        // 先上传文件（如果有的话）
        let uploadedFiles = [];
        if (this.selectedFiles.length > 0) {
          console.log("先上传文件（如果有的话）=========================this.selectedFiles.length:"+this.selectedFiles.length);
          try {
            uploadedFiles = await this.uploadFiles();
          } catch (error) {
            console.error('文件上传失败:', error);
            Message.error('文件上传失败，无法发送消息');
            return;
          }
        }
        
        // 创建用户消息
        const messageContent = this.question;
        const userMessage = {
          record_id: this.getUUID(),
          content: messageContent,
          is_from_self: true,
          timestamp: +new Date(),
          is_final: true,
          is_loading: false,
          files: uploadedFiles // 添加文件信息
        };
        this.msgList.push(userMessage);
        
        // 清空输入框
        this.question = '';
        
        // 发送消息
        this.sendQuestion({
          content: messageContent,
          files: uploadedFiles,
          timestamp: userMessage.timestamp
        });
      }
    },


    /**
     * 验证会话ID是否为UUID格式
     * @param {string} id 会话ID
     * @returns {boolean} 是否为有效的UUID格式
     */
    isValidUUID(id) {
      if (!id) return false;
      const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      return uuidRegex.test(id);
    },

    /**
     * 执行问题发出
     */
    async sendQuestion(item) {
      if (this.bullhornOpen) {
        this.handleOverallAudio();
      }

      console.log("发送问题:", item.content);
      
      // 检查当前会话ID是否为UUID格式
      const currentConversationId = this.currentConversation ? this.currentConversation.id : null;
      if (currentConversationId && !this.isValidUUID(currentConversationId)) {
        console.warn('⚠️ 当前会话ID不是UUID格式，无法发送消息:', currentConversationId);
        Message.error('会话ID格式不正确，无法发送消息。请重新开始对话。');
        return;
      }
      
      // 检查是否已经存在对应的AI消息，避免重复创建
      const existingAiMessage = this.msgList.find(msg => 
        msg.is_from_self === false && 
        msg.timestamp > item.timestamp - 1000 && // 1秒内的消息
        msg.loading_message === true
      );
      
      let aiMessage;
      if (existingAiMessage) {
        // 使用已存在的AI消息
        aiMessage = existingAiMessage;
        console.log("使用已存在的AI消息:", aiMessage.record_id);
      } else {
        // 添加AI消息占位符
        aiMessage = {
          record_id: this.getUUID(),
          content: '',
          is_from_self: false,
          timestamp: +new Date(),
          is_final: false,
          loading_message: true,
          showOption: true,
          isPlaying: false
        };
        this.msgList.push(aiMessage);
        console.log("创建新的AI消息:", aiMessage.record_id);
      }

      // 构建Dify格式的文件信息
      const difyFiles = this.buildDifyFiles(item.files || []);
      
      // 获取当前用户ID（异步）
      const userId = await this.getCurrentUserId();
      
      // 使用本项目的API发送消息
      const requestData = {
        message: item.content,
        userId: userId,
        conversationId: currentConversationId, // 使用当前会话ID（必须是UUID格式）
        createNewConversation: !currentConversationId, // 如果没有会话ID则创建新会话
        files: difyFiles // 添加Dify格式的文件参数
      };
      
      console.log('📤 发送请求数据:', requestData);

      this.currentStream = sendChatMessageStream(
        requestData,
        (data) => {
          // 确保用户消息的loading消失
          const userIndex = this.msgList.findIndex(m => m.request_id === item.request_id && m.is_from_self)
          
          //console.log('🔍 收到流式数据:', data, '类型:', typeof data);
          
          if (typeof data === 'object' && data.type === 'conversation') {
            // 会话ID处理
            //console.log('✅ 收到会话ID:', data.conversationId);
            
            // 检查是否已有当前会话，如果有则更新，否则创建新会话
            if (this.currentConversation && this.currentConversation.id) {
              // 更新现有会话的ID
              //console.log('🔄 更新现有会话ID:', this.currentConversation.id, '->', data.conversationId);
              this.$emit('conversation-updated', {
                oldId: this.currentConversation.id,
                newId: data.conversationId,
                conversation: {
                  id: data.conversationId,
                  name: this.currentConversation.name || (item.content.length > 20 ? item.content.substring(0, 20) + '...' : item.content),
                  inputs: {},
                  status: 'normal',
                  created_at: Math.floor(Date.now() / 1000),
                  updated_at: Math.floor(Date.now() / 1000)
                }
              });
            } else {
              // 创建新会话
              console.log('🆕 创建新会话，会话ID:', data.conversationId);
              this.$emit('conversation-created', {
                id: data.conversationId,
                name: item.content.length > 20 ? item.content.substring(0, 20) + '...' : item.content,
                inputs: {},
                status: 'normal',
                created_at: Math.floor(Date.now() / 1000),
                updated_at: Math.floor(Date.now() / 1000)
              });
            }
          } else if (typeof data === 'string') {
            // 流式内容处理
            const messageIndex = this.msgList.findIndex(msg => msg.record_id === aiMessage.record_id);
            if (messageIndex !== -1) {
              const currentContent = this.msgList[messageIndex].content;
              const newContent = currentContent + data;
              this.$set(this.msgList[messageIndex], 'content', newContent);
              this.$set(this.msgList[messageIndex], 'loading_message', false);
              this.$nextTick(() => {
                this.scrollToBottom();
              });
            }
          }
        },
        (error) => {
          console.error('流式响应错误:', error);
          Message.error('发送消息失败: ' + error.message);
          // 确保用户消息的loading消失
          const userIndex = this.msgList.findIndex(m => m.request_id === item.request_id && m.is_from_self)
          if (userIndex !== -1 && this.msgList[userIndex].is_loading) {
            this.$set(this.msgList[userIndex], 'is_loading', false)
          }
          const messageIndex = this.msgList.findIndex(msg => msg.record_id === aiMessage.record_id);
          if (messageIndex !== -1) {
            this.$set(this.msgList[messageIndex], 'content', '发送失败: ' + error.message);
            this.$set(this.msgList[messageIndex], 'loading_message', false);
            this.$set(this.msgList[messageIndex], 'is_final', true);
            this.$set(this.msgList[messageIndex], 'showOption', true);
          }
          this.answering = false;
          this.isThinking = false;
        },
        () => {
          // 完成回调
          console.log('流式响应完成');
          // 确保用户消息的loading消失
          const userIndex = this.msgList.findIndex(m => m.request_id === item.request_id && m.is_from_self)
          if (userIndex !== -1 && this.msgList[userIndex].is_loading) {
            this.$set(this.msgList[userIndex], 'is_loading', false)
          }
          const messageIndex = this.msgList.findIndex(msg => msg.record_id === aiMessage.record_id);
          if (messageIndex !== -1) {
            this.$set(this.msgList[messageIndex], 'loading_message', false);
            this.$set(this.msgList[messageIndex], 'is_final', true);
            this.$set(this.msgList[messageIndex], 'showOption', true);
          }
          this.answering = false;
          this.isThinking = false;
          
          // 通知父组件AI回复完成
          if (messageIndex !== -1) {
            this.sendMessage(this.msgList[messageIndex]);
          }
        }
      );

      this.isThinking = true;
      this.question = '';

      // 问题发出后，对话框立即滚动至底部
      this.$nextTick(() => {
        this.scrollToBottom();
      });
    },

    /**
     * 获取当前用户ID
     */
    async getCurrentUserId() {
      // 优先使用props中的用户ID，如果没有则使用用户服务
      if (this.userId) {
        return this.userId;
      }
      return await getCurrentUserId();
    },

    /**
     * 生成UUID
     */
    getUUID() {
      return 'msg_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
    },

    /**
     * 停止生成答案
     */
    onStopStream() {
      if (this.currentStream) {
        this.currentStream.abort();
        this.currentStream = null;
      }
      //结束语音播报
      this.handleStopAllAudio();
      this.answering = false;
      this.isThinking = false;
    },

    /**
     * 清除上下文
     */
    clearChatHandler() {
      this.$emit('clearChat', 'relation');
      this.msgList = [];
    },

    /**
     * 自动播音开关
     */
    bullhornPlayHandler() {
      this.bullhornOpen = !this.bullhornOpen;
      if (this.bullhornOpen) Message('自动播放已开启，再次点击可关闭播放')
      this.$emit('bullhornOpen', this.bullhornOpen)
    },

    /**
     * 语音通话
     */
    phoneCallHandler() {
      // 如果正在录音则停止
      if (this.recordState == 1) {
        this.endRadios(false);
      }
      this.handleStopAllAudio();

      this.isCalling = true;
      Message.info('AI语音通话功能暂未实现');
    },

    // 重置语音变量
    resetAll() {
      this.startY = 0
      this.moveY = 0
      this.timeNum = 0
      this.recordState = 0
      this.isRadiosShow = false
      this.recordTip = '语音输入（转文字）'
    },

    /**
     * 打开录音（占位符实现）
     */
    async startRadios() {
      Message.info('语音录制功能暂未实现');
      this.recordState = 1;
    },

    /**
     * 结束录音（占位符实现）
     */
    endRadios(isSend) {
      if (Number(this.timeNum) < 2) {
        Message('录制时间过短')
      } else {
        this.recordState = 2;
        if (isSend) {
          this.sendVoice()
        } else {
          this.isRecordLoading = false;
          this.resetAll()
        }
      }
    },

    /**
     * 发送录音（占位符实现）
     */
    async sendVoice() {
      Message.info('语音识别功能暂未实现');
      this.isRecordLoading = false;
      this.resetAll()
    },

    // 语音播报处理
    async handlePlayAudio(item) {
      if (this.isCalling) {
        Message('正在通话中')
        return;
      }
      
      if (!item.content) {
        Message.warning('没有可播放的内容');
        return;
      }

      try {
        // 使用浏览器原生语音合成
        const result = await nativeTextToSpeech(item.content, {
          rate: 1,
          pitch: 1,
          volume: 0.8
        });
        
        if (result.success) {
          Message.success('开始语音播报');
        } else {
          Message.error(result.message);
        }
      } catch (error) {
        console.error('语音播报失败:', error);
        Message.error('语音播报失败');
      }
    },

    /**
     * 复制文本
     * @param item
     */
    async copyContent(item) {
      if (!item.content) {
        Message.warning('没有可复制的内容');
        return;
      }

      const success = await copyToClipboard(item.content);
      if (success) {
        Message.success('复制成功');
      } else {
        Message.error('复制失败');
      }
    },

    // 根据参考提问（直接在本组件内触发，避免冒泡到父级再次触发）
    askByReference(question) {
      this.beginQuestion(question)
    },

    // 监听用户端/管理端体验侧的ws事件
    listenClientAndManageEvent() {
      // 这里可以监听聊天相关的事件
      console.log('监听聊天事件');
    },

    // 监听公共的ws事件
    listenCommonEvent() {
      // 这里可以监听公共事件
      console.log('监听公共事件');
    },

    handleOutsideClick(event) {
      // 处理外部点击事件
    },

    // 重置游标
    resetCursor() {
      this.newAnswerContent = ''
      this.answerContent = ''
      this.chatsContent = [];
      this.type = null;
      this.is_final_number = null;
      this.isTyping = false;
    },

    // 工具方法
    getUUID() {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        const r = Math.random() * 16 | 0;
        const v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
      });
    },


    

    scrollToBottom() {
      const container = document.querySelector('.chat-messages');
      if (container) {
        container.scrollTop = container.scrollHeight;
      }
    },

    // 停止所有音频播放
    handleStopAllAudio() {
      stopAllAudio();
      
      // 停止语音合成
      if ('speechSynthesis' in window) {
        speechSynthesis.cancel();
      }
      
      console.log('已停止所有音频播放');
    },

    handleOverallAudio() {
      // 处理整体音频
      console.log('处理整体音频');
    },

    initWebSocket() {
      // 初始化WebSocket连接
      console.log('初始化WebSocket连接');
    },
    
    /**
     * 加载会话消息
     * @param messages 会话消息列表
     */
    loadConversationMessages(messages) {
      this.msgList = messages || [];
      this.$nextTick(() => {
        this.scrollToBottom();
      });
    },
    
    /**
     * 从 Dify API 加载会话消息
     * @param conversationId 会话ID
     * @param userId 用户ID
     */
    async loadConversationMessagesFromAPI(conversationId, userId) {
      if (!conversationId) {
        this.msgList = [];
        return;
      }
      
      // 检查会话ID格式，如果是数字格式（本地数据库ID），则跳过Dify API调用
      if (typeof conversationId === 'string' && /^\d+$/.test(conversationId)) {
        console.log('⚠️ 检测到本地数据库会话ID，跳过Dify API调用:', conversationId);
        this.msgList = [];
        return;
      }
      
      // 检查是否是有效的UUID格式
      const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      if (!uuidRegex.test(conversationId)) {
        console.log('⚠️ 会话ID不是有效的UUID格式，跳过Dify API调用:', conversationId);
        this.msgList = [];
        return;
      }
      
      try {
        // 导入 Dify API 方法
        const { getMessages } = await import('@/api/dify/api_lx');
        
        const result = await getMessages(conversationId, userId, 50);
        console.log('📥 加载的历史消息:', result);
        
        if (result.success && result.data && result.data.length > 0) {
          // 将 Dify API 返回的消息转换为组件需要的格式
          const messages = [];
          result.data.forEach((msg, index) => {
            // 添加用户消息
            if (msg.query) {
              messages.push({
                content: msg.query,
                is_from_self: true,
                timestamp: msg.created_at * 1000,
                record_id: msg.id + '_user'
              });
            }
            
            // 添加AI回复
            if (msg.answer) {
              messages.push({
                content: msg.answer,
                is_from_self: false,
                timestamp: msg.created_at * 1000,
                record_id: msg.id + '_ai'
              });
            }
          });
          
          this.msgList = messages;
          this.$nextTick(() => {
            this.scrollToBottom();
          });
        } else {
          this.msgList = [];
        }
      } catch (error) {
        console.error('加载对话历史失败:', error);
        
        // 根据错误类型提供更友好的提示
        let errorMessage = '加载对话历史失败';
        const errorMsg = error.message || '';
        
        if (errorMsg.includes('会话不存在') || errorMsg.includes('404')) {
          errorMessage = '该会话不存在，可能已被删除。请选择其他会话或创建新会话。';
        } else if (errorMsg.includes('API认证失败') || errorMsg.includes('401')) {
          errorMessage = 'API认证失败，请联系管理员检查配置';
        } else if (errorMsg.includes('API访问被拒绝') || errorMsg.includes('403')) {
          errorMessage = 'API访问被拒绝，请联系管理员检查权限';
        } else {
          errorMessage = '加载对话历史失败：' + (error.message || '未知错误');
        }
        
        this.$message.error(errorMessage);
        this.msgList = [];
      }
    },
    
    /**
     * 发送消息并通知父组件
     * @param message 消息内容
     */
    sendMessage(message) {
      // 发送消息到父组件
      this.$emit('message-sent', message);
    }
  }
};
</script>

<style lang="less">
.timestamp {
  font-weight: 400;
  font-size: 16px;
  line-height: 16px;
  text-align: center;
  color: var(--color-text-caption);
  margin: 16px 0;
}

.q-loading {
  font-size: 24px;
  color: #999;
  padding: 20px 0px;
}

.answer-option {
  margin-bottom: 5px;
  margin-top: 10px;
  display: flex;
  justify-items: center;
  gap: 12px;
  flex-direction: row;

  .answer-btn {
    cursor: pointer;
    display: flex;
    justify-items: center;
  }

  .answer-btn img {
    width: 16px;
    height: 16px;
  }

  .trans_icon {
    transform-origin: center;
    transform: rotate(180deg);
  }

  .answer-popover {
    min-width: 50px !important;
    padding: 6px !important;
    text-align: center !important;
  }
}

.tip {
  text-align: center;
  font-size: 12px;
  color: #999;
  margin-top: 8px;
}

/* 聊天容器样式 */
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  background: #f8f9fa;
}

.message {
  display: flex;
  margin-bottom: 20px;
  align-items: flex-start;
}

.user-message {
  flex-direction: row-reverse;
}

.message-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 10px;
  flex-shrink: 0;
}

.user-avatar-small {
  background: #2196f3;
  color: white;
}

.ai-avatar-small {
  background: #f0f0f0;
}

.ai-avatar-small img {
  width: 32px;
  height: 32px;
  border-radius: 50%;
}

.message-bubble {
  max-width: 70%;
  padding: 12px 16px;
  border-radius: 12px;
  position: relative;
}

.user-bubble {
  background: #2196f3;
  color: white;
}

.ai-bubble {
  background: white;
  border: 1px solid #e6e6e6;
}

.message-content {
  word-wrap: break-word;
}

.question-text {
  line-height: 1.5;
}

.answer-text {
  line-height: 1.6;
  color: #333;
}

/* 折叠的思考块样式 */
.think-block {
  margin-top: 8px;
  border: 1px dashed #e0e0e0;
  border-radius: 6px;
  background: #fafafa;
  color: #666;
}
.think-block > summary {
  cursor: pointer;
  padding: 6px 10px;
  list-style: none;
  font-size: 12px;
  color: #888;
}
.think-block[open] > summary {
  color: #666;
}
.think-block > pre {
  margin: 0;
  padding: 10px;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-size: 12px;
  line-height: 1.6;
}

/* 欢迎消息样式 */
.header-bubble {
  width: 100%;
  display: flex;
  justify-content: center;
  margin-bottom: 20px;
}

.bubble-container {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 20px;
  padding: 30px;
  color: white;
  max-width: 600px;
  text-align: center;
}

.gif-container img {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  margin-bottom: 20px;
}

.welcome-title {
  font-size: 24px;
  font-weight: 600;
  margin-bottom: 15px;
}

.welcome-txt {
  font-size: 16px;
  opacity: 0.9;
  margin-bottom: 25px;
  line-height: 1.6;
}

.suggestions-title {
  font-size: 18px;
  font-weight: 500;
  margin-bottom: 20px;
}

.suggestions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 15px;
}

.suggestion {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 12px;
  padding: 15px;
  cursor: pointer;
  transition: all 0.3s ease;
  backdrop-filter: blur(10px);
}

.suggestion:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-2px);
}

.suggestion i {
  font-size: 20px;
  margin-bottom: 8px;
  display: block;
}

.suggestion div {
  font-size: 14px;
  line-height: 1.4;
}

/* 输入区域样式 */
.input-area {
  border-top: 1px solid #e6e6e6;
  padding: 20px;
  background: white;
}

.btn-group {
  display: flex;
  justify-content: space-between;
  margin-bottom: 15px;
}

.btn-group-left,
.btn-group-right {
  display: flex;
  gap: 10px;
}

.action-btn {
  background: none;
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 8px 12px;
  cursor: pointer;
  font-size: 12px;
  color: #666;
  transition: all 0.2s;
}

.action-btn:hover {
  background: #f5f5f5;
  border-color: #2196f3;
  color: #2196f3;
}

.input-box {
  display: flex;
  gap: 10px;
  align-items: flex-end;
}

.record-btn {
  background: none;
  border: 1px solid #ddd;
  border-radius: 6px;
  width: 40px;
  height: 40px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.record-btn:hover {
  border-color: #2196f3;
  color: #2196f3;
}

.record-btn1 {
  background: #ff4444;
  color: white;
  border-color: #ff4444;
}

.input-box textarea {
  flex: 1;
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 10px 12px;
  resize: none;
  font-family: inherit;
  font-size: 14px;
  min-height: 40px;
  max-height: 120px;
  outline: none;
  transition: border-color 0.2s;
}

.input-box textarea:focus {
  border-color: #2196f3;
}

.send-btn {
  background: #2196f3;
  color: white;
  border: none;
  border-radius: 6px;
  width: 40px;
  height: 40px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s;
}

.send-btn:hover:not(:disabled) {
  background: #1976d2;
}

.send-btn:disabled {
  background: #ccc;
  cursor: not-allowed;
}

/* 加载状态样式 */
.loading {
  color: #999;
  font-size: 14px;
  font-style: italic;
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.loading::before {
  content: '';
  width: 16px;
  height: 16px;
  border: 2px solid #e0e0e0;
  border-top: 2px solid #409EFF;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 滚动条样式 */
.chat-messages::-webkit-scrollbar {
  width: 6px;
}

.chat-messages::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.chat-messages::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.chat-messages::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 文件上传样式 */
.file-upload-container {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.file-upload-btn {
  background: #f5f5f5;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 8px 12px;
  cursor: pointer;
  color: #666;
  font-size: 14px;
  transition: all 0.3s ease;
}

.file-upload-btn:hover:not(:disabled) {
  background: #e6f7ff;
  border-color: #1890ff;
  color: #1890ff;
}

.file-upload-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.selected-files {
  margin-bottom: 8px;
  padding: 8px;
  background: #f9f9f9;
  border-radius: 4px;
  border: 1px solid #e8e8e8;
}

.file-item {
  display: flex;
  align-items: center;
  padding: 4px 8px;
  margin: 2px 0;
  background: white;
  border-radius: 4px;
  border: 1px solid #e8e8e8;
  font-size: 12px;
}

.file-item i {
  margin-right: 6px;
  color: #1890ff;
}

.file-name {
  flex: 1;
  margin-right: 8px;
  color: #333;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-size {
  margin-right: 8px;
  color: #999;
  font-size: 11px;
}

.remove-file-btn {
  background: none;
  border: none;
  color: #ff4d4f;
  cursor: pointer;
  padding: 2px;
  border-radius: 2px;
  transition: background-color 0.2s;
}

.remove-file-btn:hover {
  background: #fff2f0;
}

.remove-file-btn i {
  font-size: 12px;
  margin: 0;
}

/* 消息中的文件附件样式 */
.message-files {
  margin-bottom: 8px;
}

.file-attachment {
  display: flex;
  align-items: center;
  padding: 4px 8px;
  margin: 2px 0;
  background: #f0f8ff;
  border-radius: 4px;
  border: 1px solid #d6e4ff;
  font-size: 12px;
}

.file-attachment i {
  margin-right: 6px;
  color: #1890ff;
}

.file-attachment .file-name {
  flex: 1;
  margin-right: 8px;
  color: #333;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-attachment .file-size {
  color: #999;
  font-size: 11px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .suggestions {
    grid-template-columns: 1fr;
  }

  .message-bubble {
    max-width: 85%;
  }

  .bubble-container {
    padding: 20px;
  }
}
</style>
